import { Injectable, Logger, OnModuleInit } from '@nestjs/common';
import { ModuleRef } from '@nestjs/core';
import { ConfigCenterService } from './config-center.service';

/**
 * 动态Bean服务
 * 对应 Java: SpringDynamicBean
 */
@Injectable()
export class DynamicBeanService implements OnModuleInit {
  private readonly logger = new Logger(DynamicBeanService.name);
  private readonly dynamicBeans = new Map<string, any>();
  private readonly beanFactories = new Map<string, Function>();

  constructor(
    private readonly moduleRef: ModuleRef,
    private readonly configCenter: ConfigCenterService,
  ) {}

  async onModuleInit() {
    await this.initializeDynamicBeans();
  }

  /**
   * 初始化动态Bean
   */
  private async initializeDynamicBeans(): Promise<void> {
    try {
      this.logger.log('初始化动态Bean服务...');

      // 注册默认Bean工厂
      this.registerDefaultBeanFactories();

      this.logger.log('动态Bean服务初始化完成');
    } catch (error) {
      this.logger.error('动态Bean服务初始化失败', error);
      throw error;
    }
  }

  /**
   * 注册默认Bean工厂
   */
  private registerDefaultBeanFactories(): void {
    // 注册配置Bean工厂
    this.registerBeanFactory('config', (config: any) => {
      return {
        get: (key: string, defaultValue?: any) => config[key] || defaultValue,
        set: (key: string, value: any) => {
          config[key] = value;
        },
        has: (key: string) => key in config,
        delete: (key: string) => delete config[key],
      };
    });

    // 注册服务Bean工厂
    this.registerBeanFactory('service', (serviceConfig: any) => {
      return {
        name: serviceConfig.name,
        type: serviceConfig.type,
        config: serviceConfig.config,
        enabled: serviceConfig.enabled || true,
      };
    });
  }

  /**
   * 注册Bean工厂
   * @param type Bean类型
   * @param factory 工厂函数
   */
  registerBeanFactory(type: string, factory: Function): void {
    this.beanFactories.set(type, factory);
    this.logger.log(`注册Bean工厂: ${type}`);
  }

  /**
   * 动态创建Bean
   * @param name Bean名称
   * @param type Bean类型
   * @param config 配置
   * @returns Bean实例
   */
  async createBean(name: string, type: string, config: any): Promise<any> {
    try {
      const factory = this.beanFactories.get(type);
      if (!factory) {
        throw new Error(`Bean工厂不存在: ${type}`);
      }

      const bean = factory(config);
      this.dynamicBeans.set(name, bean);

      this.logger.log(`创建动态Bean: ${name} (${type})`);
      return bean;
    } catch (error) {
      this.logger.error(`创建动态Bean失败: ${name}`, error);
      throw error;
    }
  }

  /**
   * 获取Bean实例
   * @param name Bean名称
   * @returns Bean实例
   */
  getBean(name: string): any {
    const bean = this.dynamicBeans.get(name);
    if (!bean) {
      this.logger.warn(`Bean不存在: ${name}`);
    }
    return bean;
  }

  /**
   * 检查Bean是否存在
   * @param name Bean名称
   * @returns 是否存在
   */
  hasBean(name: string): boolean {
    return this.dynamicBeans.has(name);
  }

  /**
   * 删除Bean
   * @param name Bean名称
   */
  removeBean(name: string): void {
    if (this.dynamicBeans.has(name)) {
      this.dynamicBeans.delete(name);
      this.logger.log(`删除动态Bean: ${name}`);
    }
  }

  /**
   * 获取所有Bean名称
   * @returns Bean名称列表
   */
  getBeanNames(): string[] {
    return Array.from(this.dynamicBeans.keys());
  }

  /**
   * 动态注册配置Bean
   * @param name Bean名称
   * @param config 配置
   * @returns Bean实例
   */
  async registerConfigBean(name: string, config: any): Promise<any> {
    return this.createBean(name, 'config', config);
  }

  /**
   * 动态注册服务Bean
   * @param name Bean名称
   * @param serviceConfig 服务配置
   * @returns Bean实例
   */
  async registerServiceBean(name: string, serviceConfig: any): Promise<any> {
    return this.createBean(name, 'service', serviceConfig);
  }

  /**
   * 根据配置动态创建Bean
   * @param configKey 配置键
   * @returns Bean实例
   */
  async createBeanFromConfig(configKey: string): Promise<any> {
    try {
      const config = await this.configCenter.getConfigValue(configKey);
      if (!config) {
        throw new Error(`配置不存在: ${configKey}`);
      }

      const { name, type, ...beanConfig } = config;
      if (!name || !type) {
        throw new Error(`配置格式错误: ${configKey}`);
      }

      return this.createBean(name, type, beanConfig);
    } catch (error) {
      this.logger.error(`根据配置创建Bean失败: ${configKey}`, error);
      throw error;
    }
  }

  /**
   * 批量创建Bean
   * @param configs 配置列表
   * @returns Bean实例列表
   */
  async createBeansFromConfigs(configs: any[]): Promise<any[]> {
    const beans: any[] = [];

    for (const config of configs) {
      try {
        const bean = await this.createBeanFromConfig(config.key);
        beans.push(bean);
      } catch (error) {
        this.logger.error(`批量创建Bean失败: ${config.key}`, error);
      }
    }

    return beans;
  }

  /**
   * 刷新Bean配置
   * @param name Bean名称
   * @param config 新配置
   */
  async refreshBeanConfig(name: string, config: any): Promise<void> {
    try {
      const existingBean = this.dynamicBeans.get(name);
      if (!existingBean) {
        throw new Error(`Bean不存在: ${name}`);
      }

      // 更新Bean配置
      if (existingBean.updateConfig) {
        existingBean.updateConfig(config);
      } else {
        // 重新创建Bean
        const { type, ...beanConfig } = config;
        await this.createBean(name, type, beanConfig);
      }

      this.logger.log(`刷新Bean配置: ${name}`);
    } catch (error) {
      this.logger.error(`刷新Bean配置失败: ${name}`, error);
      throw error;
    }
  }

  /**
   * 获取Bean统计信息
   * @returns 统计信息
   */
  getBeanStatistics(): any {
    return {
      totalBeans: this.dynamicBeans.size,
      beanTypes: Array.from(this.beanFactories.keys()),
      beanNames: Array.from(this.dynamicBeans.keys()),
      factoryCount: this.beanFactories.size,
    };
  }

  /**
   * 清理所有动态Bean
   */
  clearAllBeans(): void {
    this.dynamicBeans.clear();
    this.logger.log('清理所有动态Bean');
  }

  /**
   * 销毁动态Bean服务
   */
  onModuleDestroy(): void {
    this.clearAllBeans();
    this.beanFactories.clear();
    this.logger.log('动态Bean服务已销毁');
  }
}
